#ifndef BOOST__THREAD__UNILOCK_HPP
#  define BOOST__THREAD__UNILOCK_HPP

// Copyright (C) 2004-2009
// Alex Turbov, Igor Veresov
//
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)


#  include <boost/thread/details/unilock_interface_impl.hpp>
#  include <boost/thread/details/unilock_interface_wrapper.hpp>
#  include <boost/thread/default_scheduler.hpp>
#  include <boost/thread/parameterized_scheduler.hpp>

#  include <boost/mpl/list.hpp>
#  include <boost/mpl/list_c.hpp>

namespace boost {

/**
 * \brief This matrix (1x1 size) defines the only type of lock.
 *
 * \c unilock instantiated with this matrix (and default scheduler) becomes equivalent to mutex.
 *
 * \sa default_scheduler
 */
struct exclusive_lock
{
    typedef boost::mpl::list<
        boost::mpl::list_c<bool, false>
      > matrix_type;

    enum type
    {
        lock
    };
};

/**
 * \brief This matrix defines read/write locking policy.
 */
struct rw_lock
{
    typedef boost::mpl::list<                              //      | Read | Write
        boost::mpl::list_c<bool, true,  false>             // Read |  1   | 0
      , boost::mpl::list_c<bool, false, false>             // Write|  0   | 0
      > matrix_type;

    enum type
    {
        read
      , write
    };
};

template <typename Scheduler>
class unilock
  : private details::unilock_interface_impl<Scheduler>
  , public mpl::apply<
        details::lock_interface_chooser
      , details::unilock_interface_impl<Scheduler>
      >::type
  , public mpl::apply<
        details::unlock_interface_chooser
      , details::unilock_interface_impl<Scheduler>
      >::type
{
};

}
#endif                                                     // #ifndef BOOST__THREAD__UNILOCK_HPP
